package com.christina.engine.processing.impl;

import com.alibaba.fastjson.JSONObject;
import com.christina.engine.intent.IntentRecognitionEngine;
import com.christina.engine.intent.model.Intent;
import com.christina.engine.intent.model.IntentContext;
import com.christina.engine.processing.AbstractRequestProcessor;
import com.christina.engine.processing.model.ProcessingContext;
import com.christina.engine.processing.model.ProcessingResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * 意图识别处理器
 * 负责调用AI引擎识别用户意图并提取相关参数
 */
@Component
public class IntentProcessor extends AbstractRequestProcessor {

    private static final String PROCESSOR_NAME = "IntentProcessor";
    private static final int PROCESSOR_ORDER = 300; // 在上下文处理器之后执行

    private final IntentRecognitionEngine intentRecognitionEngine;

    @Autowired
    public IntentProcessor(IntentRecognitionEngine intentRecognitionEngine) {
        super(PROCESSOR_NAME, PROCESSOR_ORDER);
        this.intentRecognitionEngine = intentRecognitionEngine;
    }

    @Override
    protected ProcessingResult doProcess(ProcessingContext context) {
        logger.debug("Starting intent recognition for requestId: {}", context.getRequestId());

        try {
            // 构建意图上下文
            IntentContext intentContext = buildIntentContext(context);

            // 识别用户意图
            Intent recognizedIntent = recognizeUserIntent(context, intentContext);

            // 提取意图参数
            JSONObject intentParameters = extractIntentParameters(context, recognizedIntent);

            // 更新意图参数
            recognizedIntent.setParameters(intentParameters);

            // 将识别结果存储到处理上下文
            context.setRecognizedIntent(recognizedIntent);
            context.setProcessingData("intentContext", intentContext);
            context.setProcessingData("intentParameters", intentParameters);

            // 验证意图识别结果
            validateIntentRecognition(recognizedIntent);

            logger.debug("Intent recognition completed for requestId: {}, intent: {}, confidence: {}",
                    context.getRequestId(), recognizedIntent.getType(), recognizedIntent.getConfidence());

            return ProcessingResult.builder()
                    .success(true)
                    .shouldContinue(true)
                    .processorName(PROCESSOR_NAME)
                    .resultData("recognizedIntent", recognizedIntent)
                    .resultData("intentType", recognizedIntent.getType().name())
                    .resultData("confidence", recognizedIntent.getConfidence())
                    .resultData("parametersCount", intentParameters.size())
                    .build();

        } catch (Exception e) {
            logger.error("Error during intent recognition for requestId: {}", context.getRequestId(), e);
            throw e;
        }
    }

    /**
     * 构建意图上下文
     */
    private IntentContext buildIntentContext(ProcessingContext context) {
        IntentContext.IntentContextBuilder builder = IntentContext.builder()
                .userId(context.getUserId())
                .sessionId(context.getSessionId())
                .currentTime(LocalDateTime.now());

        // 从用户上下文中提取信息
        if (context.getUserContext() != null) {
            builder.userPreferences(extractUserPreferences(context));
        }

        // 从对话上下文中提取历史记录
        if (context.getConversationContext() != null) {
            builder.conversationHistory(extractConversationHistory(context));
        }

        // 从原始请求中提取设备信息
        if (context.getOriginalRequest().getClientInfo() != null) {
            builder.deviceInfo(extractDeviceInfo(context));
        }

        // 添加环境变量
        builder.environmentVariables(extractEnvironmentVariables(context));

        return builder.build();
    }

    /**
     * 识别用户意图
     */
    private Intent recognizeUserIntent(ProcessingContext context, IntentContext intentContext) {
        String userInput = context.getOriginalRequest().getUserInput();

        try {
            Intent intent = intentRecognitionEngine.recognizeIntent(userInput, intentContext);

            // 如果置信度太低，尝试使用兜底策略
            if (intent.getConfidence() < 0.5) {
                logger.warn("Low confidence intent recognition: {} ({}), trying fallback",
                        intent.getType(), intent.getConfidence());

                Intent fallbackIntent = tryFallbackIntentRecognition(userInput, intentContext);
                if (fallbackIntent.getConfidence() > intent.getConfidence()) {
                    intent = fallbackIntent;
                }
            }

            return intent;

        } catch (Exception e) {
            logger.error("Intent recognition failed, using fallback", e);
            return tryFallbackIntentRecognition(userInput, intentContext);
        }
    }

    /**
     * 提取意图参数
     */
    private JSONObject extractIntentParameters(ProcessingContext context, Intent intent) {
        String userInput = context.getOriginalRequest().getUserInput();

        try {
            JSONObject parameters = intentRecognitionEngine.extractParameters(userInput, intent);

            // 添加额外的上下文参数
            enrichParametersWithContext(parameters, context, intent);

            return parameters;

        } catch (Exception e) {
            logger.error("Parameter extraction failed, using empty parameters", e);
            return new JSONObject();
        }
    }

    /**
     * 验证意图识别结果
     */
    private void validateIntentRecognition(Intent intent) {
        if (intent == null) {
            throw new IllegalStateException("Intent recognition result cannot be null");
        }

        if (intent.getType() == null) {
            throw new IllegalStateException("Intent type cannot be null");
        }

        if (intent.getConfidence() < 0.0 || intent.getConfidence() > 1.0) {
            throw new IllegalStateException("Intent confidence must be between 0.0 and 1.0");
        }

        // 对于关键意图类型，要求更高的置信度
        if (isHighRiskIntent(intent.getType()) && intent.getConfidence() < 0.7) {
            logger.warn("High-risk intent {} has low confidence: {}",
                    intent.getType(), intent.getConfidence());
        }
    }

    /**
     * 尝试兜底意图识别
     */
    private Intent tryFallbackIntentRecognition(String userInput, IntentContext intentContext) {
        // 基于关键词的简单意图识别
        String lowerInput = userInput.toLowerCase();

        Intent.IntentType fallbackType = Intent.IntentType.UNKNOWN;
        double confidence = 0.3;
        String reasoning = "基于关键词的兜底识别";

        // 出行相关关键词
        if (containsAnyKeyword(lowerInput, "出行", "旅游", "去", "到", "机票", "火车", "高铁", "飞机")) {
            fallbackType = Intent.IntentType.TRAVEL_PLANNING;
            confidence = 0.6;
            reasoning = "检测到出行相关关键词";
        }
        // 聊天相关关键词
        else if (containsAnyKeyword(lowerInput, "你好", "聊天", "怎么样", "如何", "什么")) {
            fallbackType = Intent.IntentType.GENERAL_CHAT;
            confidence = 0.7;
            reasoning = "检测到聊天相关关键词";
        }
        // 用户相关关键词
        else if (containsAnyKeyword(lowerInput, "注册", "登录", "个人", "资料", "设置")) {
            fallbackType = Intent.IntentType.USER_PROFILE;
            confidence = 0.6;
            reasoning = "检测到用户相关关键词";
        }
        // 任务相关关键词
        else if (containsAnyKeyword(lowerInput, "任务", "提醒", "待办", "计划")) {
            fallbackType = Intent.IntentType.TASK_CREATION;
            confidence = 0.6;
            reasoning = "检测到任务相关关键词";
        }

        return Intent.builder()
                .type(fallbackType)
                .name(fallbackType.getDescription())
                .description(reasoning)
                .confidence(confidence)
                .parameters(new JSONObject())
                .build();
    }

    /**
     * 检查是否包含任意关键词
     */
    private boolean containsAnyKeyword(String input, String... keywords) {
        for (String keyword : keywords) {
            if (input.contains(keyword)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否为高风险意图
     */
    private boolean isHighRiskIntent(Intent.IntentType intentType) {
        return intentType == Intent.IntentType.TRAVEL_BOOKING ||
                intentType == Intent.IntentType.TRAVEL_CANCELLATION ||
                intentType == Intent.IntentType.USER_REGISTRATION ||
                intentType == Intent.IntentType.USER_LOGIN;
    }

    /**
     * 提取用户偏好
     */
    private Map<String, Object> extractUserPreferences(ProcessingContext context) {
        Map<String, Object> preferences = new HashMap<>();

        if (context.getUserContext().getPreferences() != null) {
            preferences.putAll(context.getUserContext().getPreferences().getCustomPreferences());
        }

        if (context.getUserContext().getProfile() != null) {
            preferences.put("language", context.getUserContext().getProfile().getLanguage());
        }

        return preferences;
    }

    /**
     * 提取对话历史
     */
    private java.util.List<IntentContext.ConversationHistory> extractConversationHistory(ProcessingContext context) {
        java.util.List<IntentContext.ConversationHistory> history = new ArrayList<>();

        if (context.getConversationContext().getConversationHistory() != null) {
            context.getConversationContext().getConversationHistory().forEach(turn -> {
                history.add(IntentContext.ConversationHistory.builder()
                        .userInput(turn.getUserInput())
                        .assistantResponse(turn.getAssistantResponse())
                        .recognizedIntent(turn.getRecognizedIntent())
                        .timestamp(turn.getTimestamp())
                        .build());
            });
        }

        return history;
    }

    /**
     * 提取设备信息
     */
    private IntentContext.DeviceInfo extractDeviceInfo(ProcessingContext context) {
        var clientInfo = context.getOriginalRequest().getClientInfo();

        return IntentContext.DeviceInfo.builder()
                .deviceType(clientInfo.getDeviceType())
                .platform(clientInfo.getPlatform())
                .userAgent(clientInfo.getUserAgent())
                .ipAddress(clientInfo.getIpAddress())
                .location(clientInfo.getLocation())
                .build();
    }

    /**
     * 提取环境变量
     */
    private Map<String, String> extractEnvironmentVariables(ProcessingContext context) {
        Map<String, String> env = new HashMap<>();

        env.put("requestId", context.getRequestId());
        env.put("requestTime", context.getOriginalRequest().getRequestTime().toString());
        env.put("requestType", context.getOriginalRequest().getRequestType().name());

        return env;
    }

    /**
     * 使用上下文信息丰富参数
     */
    private void enrichParametersWithContext(JSONObject parameters, ProcessingContext context, Intent intent) {
        // 添加用户ID和会话ID
        parameters.put("userId", context.getUserId());
        parameters.put("sessionId", context.getSessionId());

        // 根据意图类型添加特定的上下文信息
        switch (intent.getType()) {
            case TRAVEL_PLANNING:
                enrichTravelPlanningParameters(parameters, context);
                break;
            case GENERAL_CHAT:
                enrichChatParameters(parameters, context);
                break;
            case USER_PROFILE:
                enrichUserParameters(parameters, context);
                break;
            default:
                // 添加通用上下文信息
                parameters.put("requestTime", context.getOriginalRequest().getRequestTime().toString());
        }
    }

    /**
     * 丰富出行规划参数
     */
    private void enrichTravelPlanningParameters(JSONObject parameters, ProcessingContext context) {
        // 如果没有指定出发时间，默认为明天
        if (!parameters.containsKey("departureTime")) {
            parameters.put("departureTime", LocalDateTime.now().plusDays(1).toString());
        }

        // 如果没有指定人数，默认为1人
        if (!parameters.containsKey("passengerCount")) {
            parameters.put("passengerCount", 1);
        }

        // 添加用户偏好的交通方式
        if (context.getUserContext() != null &&
                context.getUserContext().getPreferences() != null) {
            var prefs = context.getUserContext().getPreferences().getCustomPreferences();
            if (prefs.containsKey("preferredTransportMode")) {
                parameters.put("preferredTransportMode", prefs.get("preferredTransportMode"));
            }
        }
    }

    /**
     * 丰富聊天参数
     */
    private void enrichChatParameters(JSONObject parameters, ProcessingContext context) {
        // 添加对话历史长度
        if (context.getConversationContext() != null) {
            int historySize = context.getConversationContext().getConversationHistory().size();
            parameters.put("conversationHistorySize", historySize);
            parameters.put("currentTopic", context.getConversationContext().getCurrentTopic());
        }
    }

    /**
     * 丰富用户参数
     */
    private void enrichUserParameters(JSONObject parameters, ProcessingContext context) {
        if (context.getUserContext() != null) {
            parameters.put("hasProfile", context.getUserContext().getProfile() != null);
            parameters.put("hasPreferences", context.getUserContext().getPreferences() != null);
        }
    }

    @Override
    protected void preProcess(ProcessingContext context) {
        super.preProcess(context);
        context.updateState("RECOGNIZING_INTENT");
    }

    @Override
    protected void postProcess(ProcessingContext context, ProcessingResult result) {
        super.postProcess(context, result);
        if (result.isSuccess()) {
            context.updateState("INTENT_RECOGNIZED");
        } else {
            context.updateState("INTENT_RECOGNITION_FAILED");
        }
    }

    @Override
    public boolean supports(ProcessingContext context) {
        // 意图识别处理器支持所有已验证且已加载上下文的请求
        return context != null &&
                context.getOriginalRequest() != null &&
                context.getUserId() != null &&
                context.getSessionId() != null &&
                context.getUserContext() != null &&
                context.getConversationContext() != null;
    }

    @Override
    protected ProcessingResult handleError(ProcessingContext context, Exception exception) {
        logger.warn("Intent recognition failed, using fallback intent for requestId: {}",
                context.getRequestId(), exception);

        try {
            // 创建兜底意图
            Intent fallbackIntent = Intent.builder()
                    .type(Intent.IntentType.UNKNOWN)
                    .name("未知意图")
                    .description("意图识别失败，使用兜底处理")
                    .confidence(0.1)
                    .parameters(new JSONObject())
                    .build();

            context.setRecognizedIntent(fallbackIntent);
            context.setProcessingData("intentRecognitionError", exception.getMessage());

            return ProcessingResult.builder()
                    .success(true) // 虽然识别失败，但使用兜底意图继续处理
                    .shouldContinue(true)
                    .processorName(PROCESSOR_NAME)
                    .resultData("recognizedIntent", fallbackIntent)
                    .resultData("intentType", fallbackIntent.getType().name())
                    .resultData("confidence", fallbackIntent.getConfidence())
                    .resultData("fallbackUsed", true)
                    .resultData("error", exception.getMessage())
                    .build();

        } catch (Exception e) {
            logger.error("Failed to create fallback intent for requestId: {}", context.getRequestId(), e);
            return super.handleError(context, e);
        }
    }
}
